package net.kazed.nextaction.database.serialize;

import java.util.HashMap;
import java.util.Map;

import net.kazed.nextaction.database.GtdContext;

import org.xml.sax.Attributes;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.net.Uri;

public class ContextHandler extends AbstractElementHandler implements ElementHandlerContext<RestoreContext> {

    private ContentResolver contentResolver;
    private RestoreContext currentContext;
    private Map<Integer, Integer> contextIdTranslation;

    public ContextHandler(ContentResolver contentResolver) {
        super();
        this.contentResolver = contentResolver;
        contextIdTranslation = new HashMap<Integer, Integer>();
        
        addElementHandler(RestoreContext.ID, new ContextIdHandler(this));
        addElementHandler(RestoreContext.PARENT_ID, new ContextParentIdHandler(this));
        addElementHandler(RestoreContext.NAME, new ContextNameHandler(this));
    }

    public RestoreContext getCurrentContext() {
        return currentContext;
    }

    @Override
    public void startElement(String name, Attributes attributes,
            ParserState state) {
        currentContext = new RestoreContext();
    }

    @Override
    public void endElement(String name, ParserState state) {
        GtdContext gtdContext = new GtdContext(currentContext.id,
                currentContext.name, 0, 0);
        Integer parentId = contextIdTranslation.get(currentContext.parentId);
        if (parentId == null) {
            parentId = currentContext.parentId;
        }
        gtdContext.setParentContextId(parentId);
        ContentValues values = new ContentValues();
        gtdContext.toValues(values);
        Uri itemUri = ContentUris.withAppendedId(GtdContext.CONTENT_URI, gtdContext.getId());
        int count = contentResolver.update(itemUri, values, null, null);
        if (count == 0) {
            Uri newContextUri = contentResolver.insert(GtdContext.CONTENT_URI, values);
            String idSegment = newContextUri.getLastPathSegment();
            Integer newContextId = Integer.valueOf(idSegment);
            contextIdTranslation.put(currentContext.id, newContextId);
        } else {
            contentResolver.update(itemUri, values, null, null);
            contextIdTranslation.put(currentContext.id, currentContext.id);
        }
        currentContext = null;
    }

    public RestoreContext getContextData() {
        return currentContext;
    }

    /**
     * @return Translation map from old ID to new ID.
     */
    public Map<Integer, Integer> getContextIdTranslation() {
        return contextIdTranslation;
    }

    private static class ContextIdHandler extends AbstractElementHandlerWithContext<RestoreContext> {
        public ContextIdHandler(ElementHandlerContext<RestoreContext> handlerContext) {
            super(handlerContext);
        }

        @Override
        public void characters(String text, ParserState state) {
            getContextData().id = Integer.valueOf(text);
        }
    }

    private static class ContextNameHandler extends
            AbstractElementHandlerWithContext<RestoreContext> {
        public ContextNameHandler(ElementHandlerContext<RestoreContext> handlerContext) {
            super(handlerContext);
        }

        @Override
        public void characters(String text, ParserState state) {
            getContextData().name = text;
        }
        @Override
        public boolean isValueEncoded() {
            return true;
        }
    }

    private static class ContextParentIdHandler extends
            AbstractElementHandlerWithContext<RestoreContext> {
        public ContextParentIdHandler(
                ElementHandlerContext<RestoreContext> handlerContext) {
            super(handlerContext);
        }

        @Override
        public void characters(String text, ParserState state) {
            getContextData().parentId = Integer.valueOf(text);
        }
    }

}
